package sqlexplorer.ui.views;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.part.ViewPart;

import sqlexplorer.application.SqlController;
import sqlexplorer.domain.resultset.QueryResultSet;
import sqlexplorer.ui.model.ResultRow;

public class ResultSetView extends ViewPart implements Observer{
	
	public static final String ID="sqlexplorer.ui.views.resultsetview";
	
	private Composite m_parent;
	
	private TableViewer m_resultSetTableViewer;

	@Override
	public void createPartControl(Composite parent){
		m_parent=parent;
		
		//result set table
		m_resultSetTableViewer=new TableViewer(parent,SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
		createColumns(parent,m_resultSetTableViewer,new String[0]);
		m_resultSetTableViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
		
		final Table table=m_resultSetTableViewer.getTable();
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		
		m_resultSetTableViewer.setContentProvider(new ArrayContentProvider());
		
		SqlController.getInstance().addObserver(this);
		
		//test
		/*update(SqlController.getInstance(),"queryFinished");
		update(SqlController.getInstance(),"queryFinished");*/
	}
	
	@Override
	public void setFocus(){
		m_resultSetTableViewer.getControl().setFocus();
	}
	
	@Override
	public void update(Observable observable, Object argument){
		if(observable instanceof SqlController){
			if(argument.equals("queryFinished")){
				QueryResultSet qrs=SqlController.getInstance().getQueryResultSet();
				int rows=qrs.getNumberOfRows();
				List<ResultRow> resultRows=new ArrayList<ResultRow>();
				String[] columnHeaders=qrs.getColumnHeaders();
				
				for(int i=0; i<rows; i++){
					HashMap<String,String> values=new HashMap<String,String>();
					
					for(int j=0; j<columnHeaders.length; j++){
						values.put(columnHeaders[j],qrs.getValues().get(columnHeaders[j]).get(i));
					}
					
					resultRows.add(new ResultRow(values));
				}
				
				//refresh the table
				for(TableColumn tc:m_resultSetTableViewer.getTable().getColumns()){
					tc.dispose();
				}
				
				createColumns(m_parent,m_resultSetTableViewer,columnHeaders);
				m_resultSetTableViewer.setInput(resultRows.toArray(new ResultRow[0]));
			}else if(argument.equals("statementFinished")){
				//dispose the columns to indicate the successful statement
				for(TableColumn tc:m_resultSetTableViewer.getTable().getColumns()){
					tc.dispose();
				}
			}
		}
	}
	
	private void createColumns(final Composite parent,final TableViewer table,final String[] columnHeaders){
		int width=120;
		
		for(int i=0; i<columnHeaders.length; i++){
			final int j=i;
			
			TableViewerColumn col=createTableViewerColumn(columnHeaders[i],width,i);
			col.setLabelProvider(new ColumnLabelProvider(){
				@Override
				public String getText(Object element){
					if(element instanceof ResultRow){
						ResultRow rr=(ResultRow)element;
						
						return rr.getValue(columnHeaders[j]);
					}
					
					return "undefined";
				}
			});
		}
	}
	
	private TableViewerColumn createTableViewerColumn(String header,int width,int colNumber){
		final TableViewerColumn viewerCol=new TableViewerColumn(m_resultSetTableViewer,SWT.NONE);
		final TableColumn tableCol=viewerCol.getColumn();
		
		tableCol.setText(header);
		tableCol.setWidth(width);
		tableCol.setResizable(true);
		tableCol.setMoveable(false);
		
		return viewerCol;
	}
}
